﻿using RakutenProxy.Model.NopCommerce;
using RakutenProxy.Model.Rakuten;
using System;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace RakutenProxy.DataConverter
{
    public class RakNopManufacturerConverter : RakNopDataConverter<RakutenProxy.Model.Rakuten.Manufacturer, RakutenProxy.Model.NopCommerce.Manufacturer>
    {
        public RakNopManufacturerConverter(DbContext sourceDbContext, DbContext targetDbContext)
            : base(sourceDbContext, targetDbContext)
        {
        }

        private int _order = 1;

        public override void Migrate()
        {
            var rakDbContext = (RakutenDbContext)SourceContext;
            var nopDbContext = (NopCommerceEntities)TargetContext;

            var mappedIds = rakDbContext.Rakuten_NopCommerce_Manufacturer_Maps.Select(m => m.RakManufacturerId);
            var notMappedManufacturer = rakDbContext.Manufacturers.Where(m => !mappedIds.Contains(m.ManufacturerId));
            var mappedManufacturer = rakDbContext.Manufacturers.Except(notMappedManufacturer);

            foreach(var manufacturer in notMappedManufacturer)
            {
                //var manufacturer = notMappedManufacturer[i];
                var nopManufacturer = GetObjectFromSource(manufacturer);
                //nopManufacturer.DisplayOrder = i + 1;
                nopDbContext.Manufacturers.Add(nopManufacturer);
                nopDbContext.SaveChanges();
                var map = new Rakuten_NopCommerce_Manufacturer_Map { NopManufacturerId = nopManufacturer.Id, RakManufacturerId = manufacturer.ManufacturerId };
                rakDbContext.Rakuten_NopCommerce_Manufacturer_Maps.Add(map);

                var urlRecord = new UrlRecord { EntityId = nopManufacturer.Id, EntityName = "Manufacturer", Slug = HttpUtility.UrlEncode(nopManufacturer.Name), IsActive = true };
                nopDbContext.UrlRecords.Add(urlRecord);
                nopDbContext.SaveChanges();
            }

            foreach (var manufacturer in mappedManufacturer)
            {
                var map = rakDbContext.Rakuten_NopCommerce_Manufacturer_Maps.FirstOrDefault(m => m.RakManufacturerId == manufacturer.ManufacturerId);
                if (map != null)
                {
                    var nopManufacture = nopDbContext.Manufacturers.FirstOrDefault(m => m.Id == map.NopManufacturerId);
                    if (nopManufacture != null && !manufacturer.Equals(nopManufacture))
                    {
                        UpdateObjectFromSource(nopManufacture, manufacturer);
                    }
                }
            }

            rakDbContext.SaveChanges();
            nopDbContext.SaveChanges();
        }

        public override void MigrateOneRecord(int id)
        {
            var rakDbContext = (RakutenDbContext)SourceContext;
            var nopDbContext = (NopCommerceEntities)TargetContext;

            var rakManufacturer = rakDbContext.Manufacturers.FirstOrDefault(m => m.ManufacturerId == id);
            if (rakManufacturer == null)
                return;
            var map = rakDbContext.Rakuten_NopCommerce_Manufacturer_Maps.FirstOrDefault(m => m.RakManufacturerId == id);
            if (map == null)
            {
                var nopManufacturer = GetObjectFromSource(rakManufacturer);
                nopDbContext.Manufacturers.Add(nopManufacturer);
                nopDbContext.SaveChanges();

                map = new Rakuten_NopCommerce_Manufacturer_Map { NopManufacturerId = nopManufacturer.Id, RakManufacturerId = rakManufacturer.ManufacturerId };
                rakDbContext.Rakuten_NopCommerce_Manufacturer_Maps.Add(map);
                rakDbContext.SaveChanges();

                var urlRecord = new UrlRecord { EntityId = nopManufacturer.Id, EntityName = "Manufacturer", Slug = HttpUtility.UrlEncode(nopManufacturer.Name), IsActive = true };
                nopDbContext.UrlRecords.Add(urlRecord);
                nopDbContext.SaveChanges();
            }
            else
            {
                var nopManufacturer = nopDbContext.Manufacturers.FirstOrDefault(m => m.Id == map.NopManufacturerId);
                if (nopManufacturer != null)
                {
                    UpdateObjectFromSource(nopManufacturer, rakManufacturer);
                    nopDbContext.SaveChanges();
                }
            }
        }

        protected override Model.NopCommerce.Manufacturer GetObjectFromSource(Model.Rakuten.Manufacturer source)
        {
            var nopManufacturer = new Model.NopCommerce.Manufacturer();
            nopManufacturer.Name = Translate(source.ManufacturerName);
            nopManufacturer.DisplayOrder = _order++;
            nopManufacturer.ManufacturerTemplateId = 1;
            nopManufacturer.AllowCustomersToSelectPageSize = true;
            nopManufacturer.PageSizeOptions = "8, 4, 12";
            nopManufacturer.Published = true;
            nopManufacturer.CreatedOnUtc = DateTime.UtcNow;
            nopManufacturer.UpdatedOnUtc = DateTime.UtcNow;

            return nopManufacturer;
        }

        protected override void UpdateObjectFromSource(Model.NopCommerce.Manufacturer target, Model.Rakuten.Manufacturer source)
        {
            target.Name = Translate(source.ManufacturerName);
        }

        public override void RemoveOneRecord(int id)
        {
            var rakDbContext = (RakutenDbContext)SourceContext;
            var nopDbContext = (NopCommerceEntities)TargetContext;
                       
            var map = rakDbContext.Rakuten_NopCommerce_Manufacturer_Maps.FirstOrDefault(m => m.RakManufacturerId == id);
            if (map != null)
            {
                var nopManufacturer = nopDbContext.Manufacturers.FirstOrDefault(m => m.Id == map.NopManufacturerId);
                if (nopManufacturer != null)
                {
                    nopDbContext.Manufacturers.Remove(nopManufacturer);
                }

                rakDbContext.Rakuten_NopCommerce_Manufacturer_Maps.Remove(map);

                rakDbContext.SaveChanges();
                nopDbContext.SaveChanges();
            }
        }
    }
}